
package com.gitee.jmash.rbac.mapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import com.crenjoy.proto.mapper.BeanMapper;
import com.crenjoy.proto.mapper.ProtoMapper;
import com.gitee.jmash.core.orm.DtoPage;
import com.gitee.jmash.core.orm.DtoTotal;
import com.gitee.jmash.core.utils.GrpcTreeUtil;
import com.gitee.jmash.rbac.entity.RoleEntity;
import com.gitee.jmash.rbac.entity.RolesDutyEntity;
import jmash.rbac.protobuf.DsdRoleListResp;
import jmash.rbac.protobuf.RoleCreateReq;
import jmash.rbac.protobuf.RoleDutyModel;
import jmash.rbac.protobuf.RoleList;
import jmash.rbac.protobuf.RoleModel;
import jmash.rbac.protobuf.RoleModel.Builder;
import jmash.rbac.protobuf.RolePage;

/**
 * RoleMapper.
 *
 * @author <a href="mailto:service@crenjoy.com">crenjoy</a>
 */
@Mapper
public interface RoleMapper extends BeanMapper, ProtoMapper {

  RoleMapper INSTANCE = Mappers.getMapper(RoleMapper.class);


  default RoleList listRole(List<RoleEntity> list) {
    List<String> roots = new ArrayList<>();
    Map<String, RoleModel.Builder> map = new LinkedHashMap<>();
    // 数据建立父子关系
    for (RoleEntity entity : list) {
      RoleModel model = RoleMapper.INSTANCE.model(entity);
      map.put(model.getRoleId(), model.toBuilder());
      RoleModel.Builder parent = map.get(model.getParentId());
      if (parent != null) {
        parent.addChildren(model);
      } else {
        roots.add(model.getRoleId());
      }
    }
    List<String> idList = new ArrayList<>(roots);
    Collections.reverse(idList);
    // 根列表
    RoleList.Builder builder = RoleList.newBuilder();
    for (String root : idList) {
      builder.addResults(0,map.get(root));
    }
    return builder.build();
  }

  default RoleList listDetailRole(List<RoleModel> list) {
    List<RoleModel> roleModels = GrpcTreeUtil.buildTree(
        list,
        roleModel -> roleModel.getRoleId(),
        roleModel -> roleModel.getParentId(),
        RoleModel::toBuilder,
        Builder::build,
        (parentBuilder, child) -> parentBuilder.addChildren(0, child));
    return RoleList.newBuilder().addAllResults(roleModels).build();
  }

  default RoleModel model(RoleEntity entity, List<String> permCodes, List<RolesDutyEntity> dutyList) {
    RoleModel model = this.model(entity);
    if (permCodes != null && permCodes.size() > 0) {
      model = model.toBuilder().addAllPermCodes(permCodes).build();
    }
    if (dutyList != null && dutyList.size() > 0) {
      List<RoleDutyModel> dutyModelList = new ArrayList<>();
      for (RolesDutyEntity duty : dutyList) {
        RoleDutyModel.Builder dutyModel = RoleDutyModel.newBuilder();
        dutyModel.setRoleId(toProtoString(duty.getDescRoleId()));
        dutyModel.setRoleName("");
        dutyModel.setDutyType(duty.getDutyType());
        dutyModelList.add(dutyModel.build());
      }
      model = model.toBuilder().addAllRoleDutyModel(dutyModelList).build();
    }
    return model;
  }

  RolePage pageRole(DtoPage<RoleEntity, DtoTotal> page);

  RoleModel model(RoleEntity entity);

  RoleEntity create(RoleCreateReq req);

  RoleEntity clone(RoleEntity entity);

  default DsdRoleListResp getDsdRoleList(List<RoleEntity> list){
    List<RoleModel> roleModelList = new ArrayList<>();
    list.forEach(item -> {
      RoleModel model = INSTANCE.model(item);
      roleModelList.add(model);
    });
    return DsdRoleListResp.newBuilder().addAllRoleList(roleModelList).build();
  }


}
